package com.augurit.smartform.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.augurit.common.dao.SysMetaColumnDao;
import com.augurit.common.dao.SysMetaTableDao;
import com.augurit.common.entity.SysMetaTable;
import com.augurit.common.sysmeta.web.form.SysMetaColumnForm;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.smartform.dao.SmPageDao;
import com.augurit.smartform.dao.SmartFormDao;
import com.augurit.smartform.entity.SmPage;
import com.augurit.smartform.service.IComponentDefinitionService;
import com.augurit.smartform.service.IComponentRegisterService;
import com.augurit.smartform.service.IDesignerSupportService;
import com.augurit.smartform.util.XMLHelper;
import com.augurit.smartform.web.component.form.ComponentRegisterForm;

@Service
@Transactional
public class DesignerSupportService implements IDesignerSupportService {
	@Autowired
	private SysMetaColumnDao sysMetaColumnDao;
	@Autowired
	private SysMetaTableDao sysMetaTableDao;
	@Autowired
	private SmartFormDao smartFormDao;
	@Autowired
	private SmPageDao smPageDao;
	@Autowired
	private IComponentRegisterService componentRegistService;
	@Autowired
	private IComponentDefinitionService componentDefinitionService;
	
	/**
	 * 从序列中查询字段ID
	 * @return
	 * cuigeqiang
	 */
	public BigDecimal getNextFieldId(){
		return smartFormDao.getFieldId();
	}
	
	/**
	 * 从序列中查询页面ID
	 * @return
	 * cuigeqiang
	 */
	public BigDecimal getNextPageId(){
		return smartFormDao.getPageId();
	}
	
	/**
	 * 得到所有表单数据
	 * @return
	 * cuigeqiang
	 */
	public List<Map> getAllParentForms(){
		List<Map> forms=new ArrayList<Map>();
		List<Map> allForms=sysMetaTableDao.getAllParentForms();
		Set<String> names=new HashSet<String>();
		for(Map smForm : allForms){
			String upperName=smForm.get("tableName").toString().toUpperCase();
			if(!names.contains(upperName)){
				forms.add(smForm);
				names.add(upperName);
			}
		}
		return forms;
	}

	/**
	 * 通过FORMID得到XML定义字符串
	 * @param formIdStr
	 * @return
	 * cuigeqiang
	 */
	public String getXmlStrByFormId(String formIdStr){
		String xmlStr=null;
		if(StringUtils.isNotBlank(formIdStr)){
			Long formId=Long.parseLong(formIdStr);
			SysMetaTable sysMetaTable=sysMetaTableDao.get(formId);
			if("Y".equals(sysMetaTable.getSmartform())){
				Document doc=this.getDocument(sysMetaTable.getRawXml());
				xmlStr=this.getTypedXmlStr(doc);
			}else{
				List<SysMetaColumnForm> columns=sysMetaColumnDao.getColumnsByTableId(formId);
				xmlStr=this.getTypedXmlStr(sysMetaTable, columns);
			}
		}
		return xmlStr;
	}
	
	/**
	 * 通过模板ID加载智能表单数据
	 * @param templateId
	 * @return
	 */
	public List<Map> getSourceDataByTemplateId(String templateId){
		List<Map> list=new ArrayList<Map>();
		if(StringUtils.isNotBlank(templateId)){
			List<Map> sourceDatas=smPageDao.getSourceDataByTemplateId(templateId);
			if(sourceDatas!=null){
				list=sourceDatas;
			}
		}
		return list;
	}
	
	/**
	 * 通过页面ID加载智能表单数据
	 * @param templateId
	 * @return
	 */
	public List<Map> getSourceDataByPageId(String pageId){
		List<Map> list=new ArrayList<Map>();
		if(StringUtils.isNotBlank(pageId)){
			Map map=new HashMap();
			list.add(map);
			Long id=Long.parseLong(pageId);
			SmPage smPage=smPageDao.get(id);
			map.put("xml", smPage.getSourceXml());
			map.put("html", smPage.getSourceHtml());
			map.put("ftl", smPage.getSourceFtl());
			map.put("clientJs", smPage.getClientJavascript());
			map.put("serverJs", smPage.getServerJavascript());
		}
		return list;
	}
	
	/**
	 * 得到所有父表单名称
	 * @return
	 * cuigeqiang
	 */
	public List<Map> getAllParentSmFormName(){
		List<Map> forms=new ArrayList<Map>();
		List<Map> allForms=sysMetaTableDao.getAllParentSmFormName();
		Set<String> names=new HashSet<String>();
		for(Map smForm : allForms){
			String upperName=smForm.get("formName").toString().toUpperCase();
			if(!names.contains(upperName)){
				forms.add(smForm);
				names.add(upperName);
			}
		}
		return forms;
	}
	
	/**
	 * 获得表单所有可用的组件
	 * @return
	 */
	@Transactional(readOnly = true)
	public Map getAllAvailableComponent(){
		Map map=new HashMap();
		ComponentRegisterForm registForm=componentRegistService.getRegistFile();
		map.put("regist", registForm.getContent());
		List<Map> componentMap=componentDefinitionService.getAllAvailableComponent();
		map.put("component", componentMap);
		return map;
	}
	
	/**
	 * 获得DOM4J的DOCUMENT对象
	 * @param xmlStr
	 * cuigeqiang
	 */
	private Document getDocument(String xmlStr){
		Document document=null;
		try {
			document=DocumentHelper.parseText(xmlStr);
			
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return document;
	}

	/**
	 * 将原始XML字符串加入TYPE属性
	 * @param document
	 * @return
	 * cuigeqiang
	 */
	private String getTypedXmlStr(Document document){
		Element element=document.getRootElement();
		element.addAttribute("type", "1");
		String typedXmlStr=document.asXML();
		return typedXmlStr;
	}

	/**
	 * 将非自定义表单的表转换成XML字符串
	 * @param table
	 * @param columns
	 * @return
	 * cuigeqiang
	 */
	private String getTypedXmlStr(SysMetaTable table,List<SysMetaColumnForm> columns){
		Element object=XMLHelper.generateDom4jElement("object");
		object.addAttribute("type", "2");
		object.addAttribute("name", table.getTableName());
		object.addAttribute("cnName", table.getTableChineseComments());
		object.addAttribute("desciption", table.getMemo());
		for(SysMetaColumnForm column : columns){
			Element field=XMLHelper.generateDom4jElement("field");
			String id="column"+column.getId();
			field.addAttribute("id", id);
			field.addAttribute("name", column.getColumnName());
			field.addAttribute("cnName", column.getColumnComments());
			field.addAttribute("javaType", column.getSqlType());
			field.addAttribute("defaultValue", column.getDefaultValue());
			if(column.getColumnLength()!=null){
				field.addAttribute("maxlength", column.getColumnLength().toString());
			}
			if(column.getColumnPrecision()!=null){
				field.addAttribute("precision", column.getColumnPrecision().toString());
			}
			if(column.getColumnScale()!=null){
				field.addAttribute("scale", column.getColumnScale().toString());
			}
			if("Y".equalsIgnoreCase(column.getNullable())){
				field.addAttribute("isNotNull", "false");
			}else if("N".equalsIgnoreCase(column.getNullable())){
				field.addAttribute("isNotNull", "true");
			}
			if("Y".equalsIgnoreCase(column.getIsIndex())){
				field.addAttribute("isIndex", "true");
			}else if("N".equalsIgnoreCase(column.getIsIndex())){
				field.addAttribute("isIndex", "false");
			}
			if("Y".equalsIgnoreCase(column.getIsUnique())){
				field.addAttribute("isUnique", "true");
			}else if("N".equalsIgnoreCase(column.getIsUnique())){
				field.addAttribute("isUnique", "false");
			}
			object.add(field);
		}
		String typedXmlStr=object.asXML();
		return typedXmlStr;
	}
}
